// #############################################################################

// FILE:   adc_ex2_soc_epwm.c

// TITLE:  ADC ePWM Triggering

// ! \addtogroup driver_example_list
// ! <h1>ADC ePWM Triggering</h1>
// !
// ! This example sets up ePWM1 to periodically trigger a conversion on ADCA.
// !
// ! \b External \b Connections \n
// !  - A0 should be connected to a signal to convert
// !
// ! \b Watch \b Variables \n
// ! - \b myADC0Results - A sequence of analog-to-digital conversion samples from
// !   pin A0. The time between samples is determined based on the period
// !   of the ePWM timer.
// !

// #############################################################################


// $Copyright:
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/

// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:

//   Redistributions of source code must retain the above copyright 
//   notice, this list of conditions and the following disclaimer.

//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the   
//   distribution.

//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.

// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
// #############################################################################

// Included Files

#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "parkclark.h"
#include "math.h"
#include "svpwm.h"

//
// Defines
//
#define RESULTS_BUFFER_SIZE     256

#define DRV8353_CS_LOW()   GPIO_writePin(GPIO_PIN_SPIB_PTE, 0)
#define DRV8353_CS_HIGH()  GPIO_writePin(GPIO_PIN_SPIB_PTE, 1)

#define CS_LOW                      GPIO_writePin(GPIO_PIN_SPIB_PTE, 0)
#define CS_HIGH                     GPIO_writePin(GPIO_PIN_SPIB_PTE, 1)


#define FAULT_STATUS_1 0x00
#define FAULT_STATUS_2 0x01
#define DRV8353_STATUS00_FAULT_BITS         (1 << 10)


#define Ts             0.0001f     // 控制周期 (100us)
#define FREQ_START      50.0f     // 起始频率 (Hz)
#define FREQ_MAX        100.0f     // 最大VF频率
// #define FREQ_START      10.0f     // 起始频率 (Hz)
// #define FREQ_MAX        200.0f     // 最大VF频率
#define DF             0.2f      // 每秒频率上升值 (Hz/s)
#define K_VF           1.0f     // 电压-频率比系数 (V/Hz)
// #define DF             10.0f      // 每秒频率上升值 (Hz/s)
// #define K_VF           0.02f     // 电压-频率比系数 (V/Hz)
#define PI             3.1415926f


float freq = FREQ_START;
//
// Globals
//
float32_t myADC0Results[RESULTS_BUFFER_SIZE];   // Buffer for results
float32_t myADC1Results[RESULTS_BUFFER_SIZE];
uint16_t index;                              // Index into result buffer
volatile uint16_t bufferFull;                // Flag to indicate buffer is full

//
// Function Prototypes
//
void initEPWM(void);


//
// Main
//
// uint16_t DRV8353_ReadReg(uint16_t regAddr) {
//     uint16_t txData = (1 << 15) | (regAddr << 11); // 读命令: Bit15=1
//     uint16_t rxData = 0;

//     SPI_writeDataBlockingNonFIFO(spi0_BASE, txData); // 发送读请求
//     while (SPI_isBusy(spi0_BASE)); // 等待传输完成

//     rxData = SPI_readDataBlockingNonFIFO(spi0_BASE); // 读取返回数据
//     return (rxData & 0x0FFF); // 返回低12位有效数据
// }

// void DRV8353_WriteReg(uint16_t regAddr, uint16_t data) {
//     uint16_t txData = (regAddr << 11) | (data & 0x07FF); // 写命令: Bit15=0

//     SPI_writeDataBlockingNonFIFO(spi0_BASE, txData); // 发送数据
//     while (SPI_isBusy(spi0_BASE)); // 等待传输完成
// }

void epwm_init()
{
    EPWM_setCounterCompareValue(epwm1_BASE,EPWM_COUNTER_COMPARE_A,9000);
    EPWM_setCounterCompareValue(epwm1_BASE,EPWM_COUNTER_COMPARE_B,9000);
    EPWM_setCounterCompareValue(epwm2_BASE,EPWM_COUNTER_COMPARE_A,9000);
    EPWM_setCounterCompareValue(epwm2_BASE,EPWM_COUNTER_COMPARE_B,9000);
    EPWM_setCounterCompareValue(epwm3_BASE,EPWM_COUNTER_COMPARE_A,9000);
    EPWM_setCounterCompareValue(epwm3_BASE,EPWM_COUNTER_COMPARE_B,9000);

    // epwm1
    EPWM_setActionQualifierAction(epwm1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
    EPWM_setActionQualifierAction(epwm1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
    EPWM_setActionQualifierAction(epwm1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	
    EPWM_setActionQualifierAction(epwm1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
    EPWM_setActionQualifierAction(epwm1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
    EPWM_setActionQualifierAction(epwm1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	

    // epwm2
    EPWM_setActionQualifierAction(epwm2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
    EPWM_setActionQualifierAction(epwm2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
    EPWM_setActionQualifierAction(epwm2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	
    EPWM_setActionQualifierAction(epwm2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
    EPWM_setActionQualifierAction(epwm2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
    EPWM_setActionQualifierAction(epwm2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	

    // epwm3
    EPWM_setActionQualifierAction(epwm3_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
    EPWM_setActionQualifierAction(epwm3_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
    EPWM_setActionQualifierAction(epwm3_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	
    EPWM_setActionQualifierAction(epwm3_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
    EPWM_setActionQualifierAction(epwm3_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
    EPWM_setActionQualifierAction(epwm3_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	
}



void main(void)
{
    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Disable pin locks and enable internal pullups.
    //
    Device_initGPIO();

    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    // 
    // Board Initialization
    // - Set up the ADC and initialize the SOC
    // - Enable ADC interrupt
    //
    Board_init();

    epwm_init(); //输出pwm波形

    
    GPIO_writePin(pvdd_enable, 1);

    GPIO_writePin(gpio_enable,1);


    // uint16_t cmd_word = (1 << 15) | ((FAULT_STATUS_1 & 0xF) << 11);
    // uint16_t cmd_word1 = (1 << 15) | ((FAULT_STATUS_2 & 0xF) << 11);
    // uint16_t cmd_word2 = (0 << 15) | ((0x02 & 0xF) << 11) | (0x70 & 0x7FF);
    // uint16_t cmd_word3 = (1 << 15) | ((0x02 & 0xF) << 11);
    // uint16_t cmd_word4 = (0 << 15) | ((0x03 & 0xF) << 11) | (0x70 & 0x7FF);
    // uint16_t cmd_word5 = (1 << 15) | ((0x03 & 0xF) << 11);
    // uint16_t cmd_word6 = (1 << 15) | ((0x04 & 0xF) << 11);
   

    
    // SPI_transmit16Bits(spi0_BASE, cmd_word);
    // uint16_t data = SPI_transmit16Bits(spi0_BASE, cmd_word);

    // // 写寄存器
    // SPI_transmit16Bits(spi0_BASE, cmd_word2);
    // uint16_t data2_1 = SPI_transmit16Bits(spi0_BASE, cmd_word3);

    // SPI_transmit16Bits(spi0_BASE, cmd_word3);
    // uint16_t data2 = SPI_transmit16Bits(spi0_BASE, cmd_word3) & 0x7FF;

    // SPI_transmit16Bits(spi0_BASE, cmd_word5);
    // uint16_t data4 = SPI_transmit16Bits(spi0_BASE, cmd_word5) & 0x7FF;

    // SPI_transmit16Bits(spi0_BASE, cmd_word6);
    // uint16_t data6 = SPI_transmit16Bits(spi0_BASE, cmd_word6) & 0x7FF;




    // 定义ud，uq
    float u_d=0.0f,u_q=0.5f;
    dq_voltage dq_obj;
    dq_obj.ud = u_d;
    dq_obj.uq = u_q;
    dq_voltage_handle dq_ptr = &dq_obj;

    // 定义ualpha,ubeta
    alphabeta_voltage alphabeta_obj;
    alphabeta_obj.ualpha = 0;
    alphabeta_obj.ubeta = 0;
    alphabeta_voltage_handle alphabeta_ptr = &alphabeta_obj;

    // 定义初始角度
    float start_electrical_angle = -90;

    // park_voltage逆变换
    park_inverse_transform(dq_ptr, alphabeta_ptr , start_electrical_angle);


    // svpwm调制pwm波形
    svpwm_set_abc(alphabeta_ptr);

    // 延时1s
    DEVICE_DELAY_US(1000000); 

    // 开环启动


    for(index = 0; index < RESULTS_BUFFER_SIZE; index++)
    {
        myADC0Results[index] = 0;
    }

    index = 0;
    bufferFull = 0;

    EINT;
    ERTM;

    dq_ptr->uq = 2.0f;
    float theta_e = 1.5f * PI;
    // float theta_e = 0.0f * PI;
    while (freq <= FREQ_MAX)
    {
        // VF核心：角度积分
        theta_e += 2.0f * PI * freq * Ts ;
        if (theta_e > 2.0f * PI) theta_e -= 2.0f * PI;

        theta_e *= 180.0f/ PI;
        // if(theta_e > 180.0f)
        // {
        //     theta_e-=360.0f;
        // }

        // 输出电压
        // dq_ptr->uq = K_VF * freq;
  
        

        // park反变换
        park_inverse_transform(dq_ptr, alphabeta_ptr , theta_e);

        // svpwm调制pwm波形
        svpwm_set_abc(alphabeta_ptr);

        // // 增加频率
        // freq += DF * Ts;

        DEVICE_DELAY_US(100);
        theta_e = theta_e * PI / 180.0f;
    }

    
    // while(1)
    // {
        
    //     // while(bufferFull == 0)
    //     // {
    //     // }
    //     // bufferFull = 0;     // Clear the buffer full flag

    //     // ESTOP0;
    // }


}


__interrupt void INT_a_current_adc_2_ISR(void)
{    
    // myADC0Results[index++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0) / 4096.0f * 2.5f * 2.0f / 80.0f * 1000.0f;
    myADC0Results[index++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);

    //
    // Set the bufferFull flag if the buffer is full
    //
    if(RESULTS_BUFFER_SIZE <= index)
    {
        index = 0;
        bufferFull = 1;
    }

    //
    // Clear the interrupt flag
    //
    ADC_clearInterruptStatus(a_current_adc_BASE, ADC_INT_NUMBER2);

    //
    // Check if overflow has occurred
    //
    if(true == ADC_getInterruptOverflowStatus(a_current_adc_BASE, ADC_INT_NUMBER2))
    {
        ADC_clearInterruptOverflowStatus(a_current_adc_BASE, ADC_INT_NUMBER2);
        ADC_clearInterruptStatus(a_current_adc_BASE, ADC_INT_NUMBER2);
    }

    //
    // Acknowledge the interrupt
    //
    Interrupt_clearACKGroup(INT_a_current_adc_2_INTERRUPT_ACK_GROUP);
}

